home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Mac Game Programming Gurus / TricksOfTheMacGameProgrammingGurus.iso / Tools / nShell™ 1.0.3 / MoreSource / cat.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-23  |  7.3 KB  |  341 lines  |  [TEXT/KAHL]

  1. /* ========== the commmand file: ==========
  2.  
  3.     cat.c
  4.     
  5.     Copyright (c) 1993,1994 Newport Software Development
  6.     
  7.     You may distribute unmodified copies of this file for
  8.     noncommercial purposes.  You may use this file as a
  9.     reference when writing your own nShell(tm) commands.
  10.     
  11.     All other rights are reserved.
  12.     
  13.    ========== the commmand file: ========== */
  14.  
  15. #define    CAT_BUF_SIZE    2048
  16.  
  17. #ifdef __MWERKS__            // CodeWarrior requires an A4 setup
  18. #include <A4Stuff.h>
  19. #endif
  20.  
  21. #include <script.h>
  22. #include <string.h>
  23.  
  24. #include "nshc.h"
  25.  
  26. #include "arg_utl.proto.h"
  27. #include "fss_utl.proto.h"
  28. #include "fss_utl2.proto.h"
  29. #include "nshc_utl.proto.h"
  30. #include "str_utl.proto.h"
  31.  
  32. // data definition - this struct is the root of all data
  33.  
  34. typedef enum { copy_none, copy_data, copy_rsrc } c_state;
  35.  
  36. typedef struct {
  37.  
  38.     int        by_file;        // 1 if files are listed, 0 if stdin
  39.  
  40.     int        got_fss;        // 0 if FSSpec calls are not available
  41.  
  42.     int        arg;            // position in arg list
  43.     
  44.     short    fref;            // file ref. number, 0 if no file open
  45.  
  46. } t_cat_data;
  47.  
  48. typedef    t_cat_data    **CDataH;
  49.  
  50. /* ======================================== */
  51.  
  52. // prototypes - utility
  53.  
  54. void cat_bad( t_nshc_parms *nshc_parms, int code );
  55. void cat_bad_file( t_nshc_parms *nshc_parms, t_nshc_calls *nshc_calls, StringPtr msg );
  56. void cat_good( t_nshc_parms *nshc_parms );
  57.  
  58. // prototypes - file copy routines
  59.  
  60. void cat_open( t_nshc_parms *nshc_parms, t_nshc_calls *nshc_calls, t_cat_data **hData );
  61. void cat_read_write( t_nshc_parms *nshc_parms, t_nshc_calls *nshc_calls, t_cat_data **hData );
  62.  
  63. // prototypes - console copy routines
  64.  
  65. void cat_console( t_nshc_parms *nshc_parms, t_nshc_calls *nshc_calls );
  66.  
  67. // prototypes - state machine
  68.  
  69. void cat_start( t_nshc_parms *nshc_parms, t_nshc_calls *nshc_calls  );
  70. void cat_continue( t_nshc_parms *nshc_parms, t_nshc_calls *nshc_calls );
  71. void cat_stop( t_nshc_parms *nshc_parms, t_nshc_calls *nshc_calls );
  72.  
  73. /* ======================================== */
  74.  
  75. // utility routines
  76.  
  77. /* ======================================== */
  78.  
  79. void cat_bad(  t_nshc_parms *nshc_parms, int code )
  80. {
  81.     nshc_parms->action = nsh_stop;
  82.     nshc_parms->result = code;
  83. }
  84.  
  85. void cat_bad_file(  t_nshc_parms *nshc_parms, t_nshc_calls *nshc_calls, StringPtr msg )
  86. {
  87.     nshc_calls->NSH_putStr_err("\pcat: File access error (");
  88.     nshc_calls->NSH_putStr_err(msg);
  89.     nshc_calls->NSH_putStr_err("\p)\r");
  90.  
  91.     nshc_parms->action = nsh_stop;
  92.     nshc_parms->result = NSHC_ERR_GENERAL;
  93. }
  94.  
  95. void cat_good(  t_nshc_parms *nshc_parms )
  96. {
  97.     nshc_parms->action = nsh_stop;
  98.     nshc_parms->result = 0;
  99. }
  100.  
  101. /* ======================================== */
  102.  
  103. // file access routines
  104.  
  105. /* ======================================== */
  106.  
  107. void cat_open( t_nshc_parms *nshc_parms, t_nshc_calls *nshc_calls, t_cat_data **hData )
  108. {
  109.     int        result;
  110.     long    dirID;
  111.     Boolean    isDir;
  112.     FSSpec    fss;
  113.     
  114.     (**hData).fref = 0;
  115.  
  116.     // =====> convert path to fsspec
  117.     
  118.     result = arg_to_fss( nshc_parms, nshc_calls, (**hData).arg, &fss );
  119.  
  120.     (**hData).arg++;
  121.     
  122.     if (result) {
  123.         cat_bad( nshc_parms, result );
  124.         return;
  125.         }
  126.     
  127.     result = fss_to_DirID( &fss, &dirID, &isDir );
  128.         
  129.     if (( result == noErr) && isDir) {
  130.         nshc_calls->NSH_putStr_err("\pcat: Skiping directory = ");
  131.         nshc_calls->NSH_putStr_err((StringPtr)fss.name);
  132.         nshc_calls->NSH_putchar('\r');
  133.         return;
  134.         }
  135.             
  136.     if ( result == fnfErr ) {
  137.         nshc_calls->NSH_putStr_err("\pcat: File not found = ");
  138.         nshc_calls->NSH_putStr_err((StringPtr)fss.name);
  139.         nshc_calls->NSH_putchar('\r');
  140.         return;
  141.         }
  142.             
  143.     if (!result)
  144.         result = fss_OpenDF((**hData).got_fss, &fss, fsRdPerm, &(**hData).fref);
  145.     
  146.     if ( result ) {
  147.         cat_bad_file( nshc_parms, nshc_calls, (StringPtr)fss.name );
  148.         return;
  149.         }
  150. }
  151.  
  152. /* ======================================== */
  153.  
  154. void cat_read_write( t_nshc_parms *nshc_parms, t_nshc_calls *nshc_calls, t_cat_data **hData )
  155. {
  156.     int        close;
  157.     int        temp;
  158.     int        result;
  159.     long    bcount;
  160.     char    buf[CAT_BUF_SIZE+1];
  161.     
  162.     result = close = 0;
  163.     
  164.     // =====> copy the data fork
  165.     
  166.     bcount = CAT_BUF_SIZE;
  167.     result = FSRead( (**hData).fref, &bcount, &buf );
  168.     
  169.     if (( result == noErr ) || ( result == eofErr )) {
  170.     
  171.         if (result == eofErr) {
  172.             close = 1;
  173.             result = 0;
  174.             }
  175.         
  176.         if (bcount) {
  177.             buf[bcount] = '\0';
  178.             nshc_calls->NSH_puts( buf );
  179.             }
  180.         
  181.         }
  182.     else
  183.         cat_bad_file( nshc_parms, nshc_calls, "\pread data" );
  184.     
  185.     // =====> close the input file
  186.     
  187.     if (close) {
  188.  
  189.         if ( (**hData).fref ) {
  190.             if ( temp = FSClose( (**hData).fref ) )
  191.                 result = temp;
  192.             (**hData).fref = 0;
  193.             }
  194.             
  195.         if (result)
  196.             cat_bad_file( nshc_parms, nshc_calls, "\pclose file" );
  197.                 
  198.         }
  199. }
  200.  
  201. /* ======================================== */
  202.  
  203. // console access routines
  204.  
  205. /* ======================================== */
  206.  
  207. void cat_console( t_nshc_parms *nshc_parms, t_nshc_calls *nshc_calls )
  208. {
  209.     long    bcount;
  210.     char    buf[LINE_MAX];
  211.     char    c;
  212.     int        i;
  213.     int        temp;
  214.     
  215.     bcount = nshc_calls->NSH_gets( buf, LINE_MAX );
  216.     
  217.     if (!bcount) return;            // wait for characters
  218.     
  219.     nshc_calls->NSH_puts( buf );    // display the line
  220.     
  221.     if ( bcount == -1 )                // end of input, set-up for exit
  222.         cat_good( nshc_parms );
  223. }
  224.  
  225. /* ======================================== */
  226.  
  227. // state machine - core routines
  228.  
  229. /* ======================================== */
  230.  
  231. void cat_start( t_nshc_parms *nshc_parms, t_nshc_calls *nshc_calls  )
  232. {
  233.     CDataH    hData;    // handle to hold our data
  234.     
  235.     nshc_parms->action = nsh_continue;
  236.  
  237.     hData = (CDataH)NewHandleClear(sizeof(t_cat_data));
  238.     
  239.     if (hData) {
  240.         (**hData).by_file = nshc_parms->argc > 1;    // if we have args, do file i/o
  241.         (**hData).arg = 1;                            // start at the arg = 1 position
  242.         (**hData).got_fss = fss_test();                // test if we can use FSSpec calls
  243.         nshc_parms->data = (Handle)hData;
  244.         }
  245.     else {
  246.         nshc_calls->NSH_putStr_err( "\pcat: Could not allocate storage.\r" );
  247.         cat_bad( nshc_parms, NSHC_ERR_MEMORY );
  248.         }
  249. }
  250.  
  251. /* ======================================== */
  252.  
  253. void cat_continue( t_nshc_parms *nshc_parms, t_nshc_calls *nshc_calls )
  254. {
  255.     CDataH    hData;
  256.  
  257.     if (hData = (CDataH)nshc_parms->data) {
  258.  
  259.         if ( (**hData).by_file ) {
  260.         
  261.             // if we are not in the middle of a file, open one
  262.  
  263.             if ( !(**hData).fref )
  264.                 cat_open( nshc_parms, nshc_calls, hData );
  265.  
  266.             // read and write some of the open file
  267.  
  268.             if ( (**hData).fref )
  269.                 cat_read_write( nshc_parms, nshc_calls, hData );
  270.  
  271.             // and see if we are done
  272.  
  273.             if ( !(**hData).fref && ( (**hData).arg >= nshc_parms->argc ) )
  274.                 cat_good( nshc_parms );
  275.                 
  276.             }
  277.         else
  278.             cat_console( nshc_parms, nshc_calls );
  279.  
  280.         }
  281. }
  282.  
  283. /* ======================================== */
  284.  
  285. void cat_stop( t_nshc_parms *nshc_parms, t_nshc_calls *nshc_calls )
  286. {
  287.     short    fRef;
  288.     CDataH    hData;
  289.     int        temp;
  290.     int        result;
  291.     
  292.     result = 0;
  293.     
  294.     if (hData = (CDataH)nshc_parms->data) {
  295.     
  296.         if ( (**hData).fref ) {
  297.             if ( temp = FSClose( (**hData).fref ) )
  298.                 result = temp;
  299.             (**hData).fref = 0;
  300.             }
  301.             
  302.         DisposeHandle(nshc_parms->data);
  303.         }
  304.         
  305.     if (result)
  306.         cat_bad_file( nshc_parms, nshc_calls, "\pclosing files" );
  307.         
  308.     nshc_parms->action = nsh_idle;
  309. }
  310.  
  311. /* ======================================== */
  312.  
  313. void main(t_nshc_parms *nshc_parms, t_nshc_calls *nshc_calls)
  314. {
  315. #ifdef __MWERKS__
  316.     long oldA4  = SetCurrentA4();
  317. #endif
  318.     
  319.     if ( !nshc_bad_version( nshc_parms, nshc_calls, NSHC_VERSION ) ) {
  320.     
  321.         switch (nshc_parms->action) {
  322.             case nsh_start:
  323.                 cat_start(nshc_parms, nshc_calls);
  324.                 break;
  325.             case nsh_continue:
  326.                 cat_continue(nshc_parms, nshc_calls);
  327.                 break;
  328.             case nsh_stop:
  329.                 cat_stop(nshc_parms, nshc_calls);
  330.                 break;
  331.             }
  332.         
  333.         }
  334.  
  335. #ifdef __MWERKS__
  336.     SetA4(oldA4);
  337. #endif
  338. }
  339.  
  340. /* ======================================== */
  341.